package com.acme.bankapp.domain.bank.account;

import com.acme.bankapp.domain.bank.client.Client;
import com.acme.bankapp.domain.bank.exception.DataIntegrityException;

/**
 * This is abstract class which implements {@link Account} interface
 *
 * @author Alexander Kotov
 */

public abstract class AbstractAccount implements Account {

    private Client client;
    protected double balance;

    public AbstractAccount(double balance) throws IllegalArgumentException {
        super();
        if (balance < 0) {
            throw new IllegalArgumentException("Negative balance");
        }
        this.balance = balance;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public double getBalance() {
        return balance;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void deposit(double amount) {
        balance += amount;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void connectWithClient(Client client) throws DataIntegrityException {
        assert (this.client == null);
        assert (client.getAccount() == this);
        if (this.client != null || client.getAccount() != this) {
            throw new DataIntegrityException("Can't connect account with client");
        }
        this.client = client;

    }

    @Override
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (o == null || getClass() != o.getClass()) {
            return false;
        }

        AbstractAccount that = (AbstractAccount) o;

        if (!client.equals(that.client)) return false;

        if (client != null) {
            if (!client.equals(that.client)) {
                return false;
            }
        } else if (that.client != null) {
            return false;
        }

        return true;
    }

    @Override
    public int hashCode() {
        return client.hashCode();
    }

    @Override
    public String toString() {
        return "Account balance = " + balance;
    }
}
